package com.teampuzzle;

import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceHolder;

import com.teampuzzle.puzzles.findNumbers;
import com.teampuzzle.puzzles.rememberWhatYouSee;
import com.teampuzzle.puzzles.clickColor;
import com.teampuzzle.puzzles.largestObject;

public class GameThread extends Thread{
	
	
private static final String TAG = GameThread.class.getSimpleName();
	
	// desired fps
	private final static int 	MAX_FPS = 50;	
	// maximum number of frames to be skipped
	private final static int	MAX_FRAME_SKIPS = 5;	
	// the frame period
	private final static int	FRAME_PERIOD = 1000 / MAX_FPS;	

	float puzzleTime;
	
	private Paint mLinePaint;
	
	public static boolean showDouble = false;
	public boolean showNewLevel = false;
	public boolean showScore = false;
	
	public int lastGame;
	
	public static final int STATE_RUNNINGPUZZLE = 1;
    public static final int STATE_GAMELOOSE = 2;
    public static final int STATE_PUZZLEWIN = 3;
    public static final int STATE_PUZZLELOOSE= 4;
    public static final int STATE_NEWLEVEL = 5;
    public static int mMode;
    
    public int displayWidth;
	public static int displayHeight;
	
	public static int paddingTop;
	public static int paddingLeft;
	// Surface holder that can access the physical surface
	private SurfaceHolder surfaceHolder;
	
	public DisplayMetrics metrics;
	
	// The actual view that handles inputs
	// and draws to the surface
	private GameView myGameView;
	
	public Player myPlayer;
	public Puzzle myPuzzle;
	public Context mContext;
	
	public final static int 
	NEWLEVEL=0,
	PUZZLECOMPLETE=1,
	PUZZLEFAIL=2,
	GAMEOVER=3,
	DOUBLESCORE=4,
	STATEAWNSER=5

	;
	
	public static Bitmap triangleBlue_texture;
	public static Bitmap triangleYellow_texture;
	public static Bitmap triangleRed_texture;
	public static Bitmap triangleGreen_texture;
	
	public static Bitmap circleBlue_texture;
	public static Bitmap circleYellow_texture;
	public static Bitmap circleRed_texture;
	public static Bitmap circleGreen_texture;
	
	public static Bitmap buttonBlue_texture;
	public static Bitmap buttonYellow_texture;
	public static Bitmap buttonRed_texture;
	public static Bitmap buttonWhite_texture;
	public static Bitmap buttonGreen_texture;
	public static Bitmap time_texture;
	public static Bitmap time_texture_red;
	public static Bitmap time_texture_blue;
	public static Bitmap background_texture;
	public static Bitmap background_texturex2;
	public static Bitmap background_texturex3;
	public static Bitmap background_texturex4;
	public static Bitmap restartButton_texture;
	public static Bitmap newlevel_texture;
	public static Bitmap fail_texture;

	//X2-knappar
	public static Bitmap x2_texture;
	public static Bitmap x3_texture;
	public static Bitmap x4_texture;
	
	//public GameThread(TeampuzzleActivity context) {
    //    gameThreadContext = context;
    //}
	

	// flag to hold game state 
	static boolean running;

	
	public void setRunning(boolean running) {
		GameThread.running = running;
	}

	public GameThread(SurfaceHolder surfaceHolder, GameView myGameView, Context myContext) {
		super();
		this.surfaceHolder = surfaceHolder;
		this.myGameView = myGameView;
		this.mContext = myContext;
	}
	
	public Puzzle generatePuzzle(int level){
		int randomPuzzleNum;
		
		int randomNum;
		if(level < 3){
			randomNum = level +1 ;
		}else if(level >= 3 && level < 6){
			randomNum = level;
		}else{
			randomNum = 6;
		}
		
		Random generator = new Random();
		randomPuzzleNum = generator.nextInt(randomNum); //generator.nextInt(6);
		randomPuzzleNum = generator.nextInt(1);

//		if(randomPuzzleNum == lastGame){
//			if(randomPuzzleNum>0){
//				randomPuzzleNum -= 1;
//			}else{
//				randomPuzzleNum += 1;
//			}
//		}
		
		lastGame = randomPuzzleNum;
		
		switch(randomPuzzleNum){	
		case 0:
			return new rememberWhatYouSee(1, level);
		case 1:
			return new findNumbers(level);
		case 2:
			return new largestObject(level);
		case 3:
			return new rememberWhatYouSee(2, level);
		case 4:
			return new rememberWhatYouSee(3, level);
		case 5:
			return new rememberWhatYouSee(1, level);
		default:
			return new largestObject(level);
		
		}
	}
	
	public Bitmap resizeBitmap(Bitmap bm, float scaleFactor){
		Matrix matrix = new Matrix();
		matrix.postScale(scaleFactor, scaleFactor);
		
		// recreate the new Bitmap and set it back
        Bitmap resizedBitmap = Bitmap.createBitmap(restartButton_texture, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
        
        return resizedBitmap;
	}
	
	public void loadContent(){
		
		
		//LADDA LJUD
		SoundHandler.SoundHandler(mContext);
		
		// LADDA TEXTURER
		buttonBlue_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.buttonblue);
		buttonRed_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.buttonred);
		buttonGreen_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.buttongreen);
		buttonYellow_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.buttonyellow);
		buttonWhite_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.buttonwhite);
		
		triangleBlue_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.trinagleb);
		triangleRed_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.trinagler);
		triangleGreen_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.trinagleg);
		triangleYellow_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.trinagley);
		
		circleBlue_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.circleb);
		circleRed_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.circler);
		circleGreen_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.circleg);
		circleYellow_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.circley);
		
		restartButton_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.button_restartbutton);
		
        restartButton_texture = resizeBitmap(restartButton_texture, 0.5f);
        
		time_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.time);
		time_texture_red = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.timered);
		time_texture_blue = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.timeblue);
		
		background_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.background);
		background_texturex2 = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.backgroundx2);
		background_texturex3 = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.backgroundx3);
		background_texturex4 = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.backgroundx4);
		
		x2_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.x2);
		x3_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.x3);
		x4_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.x4);
		
		newlevel_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.newlevel);
		fail_texture = BitmapFactory.decodeResource(mContext.getResources(), com.teampuzzle.R.drawable.fail);
		
		// STORLEK PÅ SKÄRMEN
		displayWidth = TeampuzzleActivity.displayWidth;
    	displayHeight = TeampuzzleActivity.displayHeight;
    	
    	paddingTop = (int) (TeampuzzleActivity.displayHeight * 0.15);
    	paddingLeft = (int) (TeampuzzleActivity.displayWidth * 0.10);
    	
    	Log.d("DISPLAYSIZE", displayWidth + " " + displayHeight);
	}
	
	public void addScore(){
//		if (puzzleTime >=10.0f && puzzleTime < 15.0){
//			myPlayer.addScore(100);
//		}
//		else if (puzzleTime >= 5.0f && puzzleTime < 10.0f){
//			myPlayer.addScore(50);
//		}else if (puzzleTime < 5.0f){
//			myPlayer.addScore(25);
//		}
		myPlayer.addScore(myPuzzle.calculateScore(puzzleTime));
	}
	
	public static void playSound(int sound){
		SoundHandler.play(sound);	
	}

	@Override
	public void run() {
		loadContent();
		myPlayer = new Player();
		mMode = STATE_NEWLEVEL;
		loadContent();
		
		Canvas canvas;
		Log.d(TAG, "Starting game loop");

		long beginTime;		// the time when the cycle begun
		long lastTime;
		long timeDiff;		// the time it took for the cycle to execute
		int sleepTime;		// ms to sleep (<0 if we're behind)
		int framesSkipped;	// number of frames being skipped 

		sleepTime = 0;
		
		lastTime = System.currentTimeMillis();
		

		puzzleTime = (float) 20.0;


		while (running) {
			canvas = null;
			
			// try locking the canvas for exclusive pixel editing
			// in the surface
			if(mMode == STATE_PUZZLEWIN){
				SoundHandler.play(PUZZLECOMPLETE);
				myPlayer.addTime(myPuzzle.getTimeAdd());
				addScore();
				myPlayer.addStreak(1);
				//mMode = STATE_NEWLEVEL;
				
				showScore = true;
				Timer t = new Timer(); 
		        t.schedule(new TimerTask() {            
		        	public void run() { 
		        		showScore = false;
		        		//STATE_ANSWER? REMEMBER?
		        	} 
		        }, 2000);
			}
			
			if(mMode == STATE_NEWLEVEL || mMode == STATE_PUZZLELOOSE || mMode == STATE_PUZZLEWIN){
				
				if(mMode == STATE_PUZZLELOOSE){
					SoundHandler.play(PUZZLEFAIL);
					myPlayer.setStreak(0);
					if(myPlayer.level > 6){
						myPlayer.addTime((float) myPlayer.level - 3);
					}else{
						myPlayer.addTime(-3f);	
					}
				}
				if(mMode == STATE_NEWLEVEL){
					//SoundHandler.reset(NEWLEVEL);
					//SoundHandler.play(PUZZLECOMPLETE);
					showNewLevel = true;
					Timer t = new Timer(); 
			        t.schedule(new TimerTask() {            
			        	public void run() { 
			        		showNewLevel = false;
			        		//STATE_ANSWER? REMEMBER?
			        	} 
			        }, 2000);
				}
				
				Log.d(TAG, "GENERATE PUZZLE");
				myPuzzle = generatePuzzle(myPlayer.getLevel());
				
				puzzleTime = 15.0f;
				
				Timer t = new Timer(); 
		        t.schedule(new TimerTask() {            
		        	public void run() { 
		        		myPuzzle.pState = Puzzle.STATE_REMEMBER;
		        		//STATE_ANSWER? REMEMBER?
		        	} 
		        }, 2000);
				
				myPuzzle.loadContent(mContext);
				
				mMode = STATE_RUNNINGPUZZLE;
			}
			
			try {
				canvas = this.surfaceHolder.lockCanvas();
				synchronized (surfaceHolder) {
					
					beginTime = System.currentTimeMillis();
					if(myPuzzle.pState != Puzzle.STATE_INTRODUCTION && myPuzzle.pState != Puzzle.STATE_REMEMBER){ // Tickar inte ner tid vid remember och introduction
						puzzleTime -= (beginTime - lastTime)/1000.0;
						myPlayer.addTime(-(beginTime - lastTime)/1000.0f);
					}
					lastTime = beginTime;
					
					framesSkipped = 0;	// resetting the frames skipped
					
					// update game state 
					this.myGameView.update();
					// render state to the screen
					// draws the canvas on the panel
					this.myGameView.render(canvas);	
					//myPuzzle.draw(canvas);
					
					if(mMode != STATE_GAMELOOSE && mMode != STATE_NEWLEVEL){
						myPuzzle.draw(canvas);
					}else{
						//myPuzzle.drawEnd(canvas);
						//myPlayer.drawEndScreen(canvas);
					}
					if(showNewLevel){
						myPlayer.drawNewLevel(canvas);	
					}
					
					if(showScore){
						myPlayer.drawScore(canvas);
					}
					if(showDouble == true && showNewLevel == false && showScore == false){
						myPlayer.drawDouble(canvas);
						
					}
					
					// calculate how long did the cycle take
					timeDiff = System.currentTimeMillis() - beginTime;
					
					// calculate sleep time
					sleepTime = (int)(FRAME_PERIOD - timeDiff);
					
					if (sleepTime > 0) {
						// if sleepTime > 0 we're OK
						try {
							// send the thread to sleep for a short period
							// very useful for battery saving
							Thread.sleep(sleepTime);	
						} catch (InterruptedException e) {}
					}
					
					while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {
						// we need to catch up
						this.myGameView.update(); // update without rendering
						sleepTime += FRAME_PERIOD;	// add frame period to check if in next frame
						framesSkipped++;
					}
				}
			} finally {
				// in case of an exception the surface is not left in 
				// an inconsistent state
				if (canvas != null) {
					surfaceHolder.unlockCanvasAndPost(canvas);
				}
			}	// end finally
			
		}
	}

}
